"use strict";
var util = require('util');
var RpcBase = require('./RpcBase.js');

var __qRequest = 'request_to_{type}';
var __qReply = 'reply_to_{appId}';

function RpcServer(service) {
	var self = this;
	self.init(function() {
		console.log('init done, id=%s', self.__id);
		__createProxy(self, service);
	});
}
util.inherits(RpcServer, RpcBase);
module.exports = RpcServer;


function __createProxy(obj, service) {
	// console.log('__createProxy');
	if (typeof service === 'function') {
		obj.__server = new service();
	} else {
		obj.__server = service;
	}
	__prepareChannel(obj);
}

function __prepareChannel(obj) {
	// console.log('__prepareChannel');
	var conn = obj.__mqconn;
	var ch = null;

	if (obj.__mqch) {
		ch = obj.__mqch;
		prepareMqRequestChannel();
		return;
	}
	conn.createChannel(function(err, channel) {
		if (err) throw err;
		obj.__mqch = channel;
		ch = channel;
		prepareMqRequestChannel();
	});

	function prepareMqRequestChannel() {
		var qRequst = __qRequest.replace('{type}', obj.__server.type);
		// console.log('create queue %s', qRequst);
		ch.assertQueue(qRequst, {
			durable: true
		});
		ch.prefetch(1); // TODO fetch reply should not set prefetch =1 ,but fetch request should set to 1 
		ch.consume(qRequst, function(msg) {
			console.log(' [receive-request]:%s', msg.content);
			ch.ack(msg);
			__handleMsg(obj, msg);
		}, {
			noAck: false
		});
	}
}


function __handleMsg(obj, msg) { // msg: {route:"xx.xx.xx",args:[xx,xx]}
	// console.log('handleMsg');
	var content = msg.content.toString();
	var json = JSON.parse(msg.content);
	var method = json.method;
	var args = json.args;
	args.push(function() {
		// var result = 'TODO';
		// console.log('callback now, arguments', arguments);
		var result = Array.prototype.slice.call(arguments);
		__reply(obj, msg, JSON.stringify(result));
	});
	obj.__server[method].apply(obj.__server, args);
}

function __reply(obj, msg, result) {
	var ch = obj.__mqch;
	var replyTo = msg.properties.replyTo;
	var replyQid = __qReply.replace('{appId}', replyTo);
	console.log(' [send-reply] =%s,replyTo=%s', result, replyQid);
	ch.sendToQueue(replyQid, new Buffer(result), {
		correlationId: msg.properties.correlationId
	});
}